home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- shadow_scn.c - Read a scene description from file, build data structures.
-
- Tim Heidmann, Silicon Graphics
- Created June 21, 1991
- Last Edit November 25, 1991
- */
-
- #include <stdio.h>
- #include <gl.h>
- #include <gl/image.h>
- #include <device.h>
- #include <math.h>
- #include <string.h>
- #include "shadows.h"
- #include "glo_obj.h"
- #include "vect.h"
-
-
- /* Default shadowed and highlit material values */
- #define MATEMISOFF 0
- #define MATAMBIOFF 4
- #define MATDIFFOFF 8
- #define MATSPECOFF 12
- #define MATSHINOFF 16
- float defaultLitMaterial[] = {
- EMISSION, 0.0, 0.0, 0.0,
- AMBIENT, 0.2, 0.2, 0.2,
- DIFFUSE, 0.8, 0.8, 0.8,
- SPECULAR, 0.0, 0.0, 0.0,
- SHININESS, 0.0,
- LMNULL
- };
- float defaultShadowMaterial[] = {
- EMISSION, 0.0, 0.0, 0.0,
- AMBIENT, 0.2, 0.2, 0.2,
- DIFFUSE, 0.0, 0.0, 0.0,
- SPECULAR, 0.0, 0.0, 0.0,
- SHININESS, 0.0,
- LMNULL
- };
- float defaultHighMaterial[] = {
- EMISSION, 0.0, 0.0, 0.0,
- AMBIENT, 0.0, 0.0, 0.0,
- DIFFUSE, 0.8, 0.8, 0.8,
- SPECULAR, 0.0, 0.0, 0.0,
- SHININESS, 0.0,
- LMNULL
- };
- #define MATDEFLEN (sizeof(defaultHighMaterial)/sizeof(float))
-
- #define LGTAMBOFF 0
- #define LGTCOLOFF 4
- #define LGTPOSOFF 8
- #define LGTSPDOFF 13
- #define LGTSPLOFF 17
- float defaultLight[] = {
- AMBIENT, 0.0, 0.0, 0.0,
- LCOLOR, 1.0, 1.0, 1.0,
- POSITION, 0.0, 0.0, 1.0, 0.0,
- SPOTDIRECTION, 0.0, 0.0, -1.0,
- SPOTLIGHT, 0.0, 180.0,
- LMNULL
- };
- #define LGTDEFLEN (sizeof(defaultLight)/sizeof(float))
- float defaultLight_posn[] = {0.0, 0.0, 10000.0};
-
- float FlatGray[] = {
- EMISSION, 0.0, 0.0, 0.0,
- AMBIENT, 1.0, 1.0, 1.0,
- DIFFUSE, 1.0, 1.0, 1.0,
- SPECULAR, 0.0, 0.0, 0.0,
- SHININESS, 20.0,
- LMNULL
- };
- float FlatGrayA[] = {
- EMISSION, 0.0, 0.0, 0.0,
- AMBIENT, 1.0, 1.0, 1.0,
- DIFFUSE, 0.0, 0.0, 0.0,
- SPECULAR, 0.0, 0.0, 0.0,
- SHININESS, 20.0,
- LMNULL
- };
- float FlatGrayH[] = {
- EMISSION, 0.0, 0.0, 0.0,
- AMBIENT, 0.0, 0.0, 0.0,
- DIFFUSE, 1.0, 1.0, 1.0,
- SPECULAR, 0.0, 0.0, 0.0,
- SHININESS, 20.0,
- LMNULL
- };
-
- float RightRed[] = {
- AMBIENT, 0.0, 0.0, 0.0,
- LCOLOR, 1.0, 0.0, 0.0,
- POSITION, 1.0, 1.0, 1.0, 0.0,
- LMNULL
- };
- float LeftBlue[] = {
- AMBIENT, 0.0, 0.0, 0.0,
- LCOLOR, 0.0, 0.0, 1.0,
- POSITION, -1.0, 1.0, 1.0, 0.0,
- LMNULL
- };
- float theLModel[] = {
- AMBIENT, 0.2, 0.2, 0.2,
- LOCALVIEWER, 0.0,
- ATTENUATION, 1.0, 0.0,
- TWOSIDE, 0.0,
- LMNULL
- };
-
- #define SS_UNDEFINED -1
- #define SS_WINDOW 0
- #define SS_LOOKAT 1
- #define SS_MODEL 2
- #define SS_XMODEL 17
- #define SS_LIGHT 3
- #define SS_POSITI 4
- #define SS_ROTATI 5
- #define SS_SCALE 6
- #define SS_TEXTUR 18
- #define SS_MATERI 7
- #define SS_SPECUL 8
- #define SS_SHININ 9
- #define SS_DIFFUS 10
- #define SS_EMISSI 11
- #define SS_AMBIEN 12
- #define SS_LCOLOR 13
- #define SS_SPOTDI 14
- #define SS_SPOTLI 15
- #define SS_JITTER 19
- #define SS_END 16
-
- struct scmd_tag {
- int index;
- char *name;
- } SceneCommands[] = {
- {SS_WINDOW, "WIN" }, /* WINDOW height near far */
- {SS_LOOKAT, "LOO" }, /* LOOKAT eyex eyey eyez gazex gazey gazez */
- {SS_MODEL , "MOD" }, /* MODEL filename (shadow-casting model) */
- {SS_XMODEL, "XMO" }, /* XMODEL filename (non shadow-casting model) */
- {SS_LIGHT , "LIG" }, /* LIGHT <light properties...> END */
- /* Light properties are AMBIENT, LCOLOR, */
- /* POSITION, SPOTDIRECTION, and SPOTLIGHT. */
- {SS_POSITI, "POS" }, /* POSITION x y z (for models) */
- /* POSITION x y z w (for lights) */
- {SS_ROTATI, "ROT" }, /* ROTATION xrot yrot zrot */
- {SS_SCALE , "SCA" }, /* SCALE s */
- {SS_TEXTUR, "TEX" }, /* TEXTURE filename */
- {SS_MATERI, "MAT" }, /* MATERIAL <material properties...> END */
- /* Material properties are EMISSION, AMBIENT,*/
- /* DIFFUSE, SPECULAR, and SHININESS. */
- {SS_SPECUL, "SPE" }, /* SPECULAR r g b (color components,0.0-1.0) */
- {SS_SHININ, "SHI" }, /* SHININESS s (Specular exp, 0.0-128.0) */
- {SS_DIFFUS, "DIF" }, /* DIFFUSE r g b */
- {SS_EMISSI, "EMI" }, /* EMISSION r g b */
- {SS_AMBIEN, "AMB" }, /* AMBIENT r g b */
- {SS_LCOLOR, "LCO" }, /* LCOLOR r g b */
- {SS_LCOLOR, "COL" }, /* COLOR r g b */
- {SS_SPOTDI, "SPOTD"}, /* SPOTDIRECTION dx dy dz */
- {SS_SPOTLI, "SPOTL"}, /* SPOTLIGHT exp spread */
- /* (exponent 0.0-128.0, spread: 0.0-90.0) */
- {SS_JITTER, "JIT" }, /* JITTER xrange yrange zrange */
- {SS_END , "END" } /* END (for material or light def)*/
- };
- #define NSCENECMDS (sizeof(SceneCommands)/sizeof(struct scmd_tag))
-
- PolyDataRec NullPolyData = {0, 0, NULL, NULL};
-
- /* Forward declarations */
- void
- AddEdge(EdgePtr edgeList, int *nEdgesp, int v1, int v2, int thisFace,
- int *iEdgep, int *iSidep);
- PolyDataPtr
- GetPolyData(glo_ObjPtr pdl);
-
-
- InitScene() {
- int i, done, localDone, count, theCommand;
- int iTmp, iList[30], iMaterial, iTexture;
- float fTmp[30], fLit[30], fHigh[30], fShad[30], x;
- long *itex, xtex, ytex;
- char cmd[60], objFileName[60];
- FILE *inf;
-
- /* Set flags and constant values */
- vmatcopy(IdentMat, scene_rotMatrix);
- iMaterial = 1;
- iTexture = 1;
-
- /* Read and parse the scene file, if specified */
- if (sceneFileName != NULL) {
- if ((inf = fopen(sceneFileName, "r")) == NULL) {
- fprintf(stderr, "Cannot open scene file %s\n", sceneFileName);
- exit(1);
- }
- fscanf(inf, "%s", cmd);
- if (strcmp(cmd, "ShadowScene") != 0) {
- fprintf(stderr, "File %s is not a Shadow Scene file.\n",
- sceneFileName);
- exit(1);
- }
-
- for (done = FALSE; !done; ) {
- count = fscanf(inf, "%s", cmd);
- if (count == EOF) {
- done = TRUE;
- continue;
- }
- switch (theCommand = FindCommand(cmd)) {
- /* Camera, and view parameters */
- case SS_WINDOW:
- count = fscanf(inf, "%f %f %f", viewWindow, viewWindow+1,
- viewWindow+2);
- break;
- case SS_LOOKAT:
- count = fscanf(inf, "%f %f %f %f %f %f", eyex, eyex+1, eyex+2,
- gazex, gazex+1, gazex+2);
- break;
-
- /* Model geometry and scene, model, light positioning */
- case SS_MODEL:
- case SS_XMODEL:
- fscanf(inf, "%s", objFileName);
- if ((obj_drawlist[nObjects]=glo_ReadObj(objFileName)) != NULL) {
- /* We've got a glo_Object file. Get edge adjacency data. */
- obj_data[nObjects] = (theCommand == SS_MODEL) ?
- GetPolyData(obj_drawlist[nObjects]) :
- &NullPolyData;
- } else if (ReadPDataObj(objFileName,
- obj_drawlist+nObjects, obj_data+nObjects)) {
- /* Got a binary geometry & data file */
- if (theCommand == SS_XMODEL) {
- /* Remove any edge data for non-shadowing objects */
- free(obj_data[nObjects]->faces);
- obj_data[nObjects]->faces = NULL;
- free(obj_data[nObjects]->edges);
- obj_data[nObjects]->edges = NULL;
- obj_data[nObjects]->nFaces = 0;
- obj_data[nObjects]->nEdges = 0;
- }
- } else {
- /* Cannot recognize this file */
- fprintf(stderr, "Cannot open object file %s\n",
- objFileName);
- exit(1);
- }
-
- /* Initialize various parameters */
- for (i=0; i<3; i++) obj_posn[nObjects][i] = 0.0;
- obj_scale[nObjects] = 1.0;
- vmatcopy(IdentMat, obj_rotMatrix[nObjects]);
- obj_litMaterial[nObjects] = -1;
- obj_texture[nObjects] = 0;
-
- nObjects++;
- break;
-
- case SS_POSITI:
- fscanf(inf, "%f %f %f", fTmp, fTmp+1, fTmp+2);
- if (nObjects > 0)
- for (i=0; i<3; i++)
- obj_posn[nObjects-1][i] = fTmp[i];
- break;
-
- case SS_ROTATI:
- fscanf(inf, "%f %f %f", fTmp, fTmp+1, fTmp+2);
- if (nObjects <= 0)
- GetRotMatrix(scene_rotMatrix, fTmp);
- else
- GetRotMatrix(obj_rotMatrix[nObjects-1], fTmp);
- break;
-
- case SS_SCALE:
- fscanf(inf, "%f", fTmp);
- if (nObjects > 0)
- obj_scale[nObjects-1] = fTmp[0];
- break;
-
- case SS_MATERI:
- /* Build lit, shadow, and hilite material definition arrays */
- if (nObjects <= 0) {
- fprintf(stderr,
- "Material definition does not follow an object.\n");
- exit(1);
- }
- for (i=0; i<MATDEFLEN; i++) fHigh[i]=defaultHighMaterial[i];
- for (i=0; i<MATDEFLEN; i++) fShad[i]=defaultShadowMaterial[i];
- for (i=0; i<MATDEFLEN; i++) fLit[i]=defaultLitMaterial[i];
-
- for (localDone = FALSE; !localDone; ) {
- fscanf(inf, "%s", cmd);
- switch (FindCommand(cmd)) {
- case SS_SPECUL:
- fscanf(inf, "%f %f %f", fLit+MATSPECOFF+1,
- fLit+MATSPECOFF+2, fLit+MATSPECOFF+3);
- for (i=1; i<4; i++)
- fHigh[MATSPECOFF+i] = fLit[MATSPECOFF+i];
- break;
- case SS_SHININ:
- fscanf(inf, "%f", fLit+MATSHINOFF+1);
- fHigh[MATSHINOFF+1] = fLit[MATSHINOFF+1];
- break;
- case SS_DIFFUS:
- fscanf(inf, "%f %f %f", fLit+MATDIFFOFF+1,
- fLit+MATDIFFOFF+2, fLit+MATDIFFOFF+3);
- for (i=1; i<4; i++)
- fHigh[MATDIFFOFF+i] = fLit[MATDIFFOFF+i];
- break;
- case SS_EMISSI:
- fscanf(inf, "%f %f %f", fLit+MATEMISOFF+1,
- fLit+MATEMISOFF+2, fLit+MATEMISOFF+3);
- for (i=1; i<4; i++)
- fShad[MATEMISOFF+i] = fLit[MATEMISOFF+i];
- break;
- case SS_AMBIEN:
- fscanf(inf, "%f %f %f", fLit+MATAMBIOFF+1,
- fLit+MATAMBIOFF+2, fLit+MATAMBIOFF+3);
- for (i=1; i<4; i++)
- fShad[MATAMBIOFF+i] = fLit[MATAMBIOFF+i];
- break;
- case SS_END:
- lmdef(DEFMATERIAL,
- obj_litMaterial[nObjects-1] = iMaterial++,
- 0, fLit);
- lmdef(DEFMATERIAL,
- obj_shadowMaterial[nObjects-1] = iMaterial++,
- 0, fShad);
- lmdef(DEFMATERIAL,
- obj_highMaterial[nObjects-1] = iMaterial++,
- 0, fHigh);
- localDone = TRUE;
- break;
- default:
- fprintf(stderr, "Unknown MATERIAL keyword: %s\n", cmd);
- break;
- }
- }
- break;
-
- case SS_TEXTUR:
- /* Read and define a texture */
- if (nObjects <= 0) {
- fprintf(stderr,
- "Texture definition does not follow an object.\n");
- exit(1);
- }
- fscanf(inf,"%s", cmd);
- ReadImg(cmd, &itex, &xtex, &ytex);
- texdef2d(obj_texture[nObjects-1] = iTexture++, 4,
- xtex, ytex, itex, 0, tex_val);
- free(itex);
- break;
-
- case SS_LIGHT:
- /* Build a light definition array */
- iTmp = 0;
- for (i=0; i<3; i++) {
- light_posn[nLights][i] = defaultLight_posn[i];
- jitter_light_range[nLights][i] = 0.0;
- }
- for (i=0; i<LGTDEFLEN; i++) fTmp[i] = defaultLight[i];
-
- for (localDone = FALSE; !localDone; ) {
- fscanf(inf, "%s", cmd);
- switch (FindCommand(cmd)) {
- case SS_AMBIEN:
- fscanf(inf, "%f %f %f", fTmp+LGTAMBOFF+1,
- fTmp+LGTAMBOFF+2, fTmp+LGTAMBOFF+3);
- break;
- case SS_LCOLOR:
- fscanf(inf, "%f %f %f", fTmp+LGTCOLOFF+1,
- fTmp+LGTCOLOFF+2, fTmp+LGTCOLOFF+3);
- break;
- case SS_POSITI:
- fscanf(inf, "%f %f %f %f", fTmp+LGTPOSOFF+1,
- fTmp+LGTPOSOFF+2, fTmp+LGTPOSOFF+3,
- fTmp+LGTPOSOFF+4);
- x = fabs(fTmp[LGTPOSOFF+4]) < 0.01 ?
- 0.01 : fTmp[LGTPOSOFF+4];
- for (i=0; i<3; i++)
- light_posn[nLights][i] = fTmp[LGTPOSOFF+1+i]/x;
- break;
- case SS_SPOTDI:
- fscanf(inf, "%f %f %f", fTmp+LGTSPDOFF+1,
- fTmp+LGTSPDOFF+2, fTmp+LGTSPDOFF+3);
- break;
- case SS_SPOTLI:
- fscanf(inf, "%f %f %f", fTmp+LGTSPLOFF+1,
- fTmp+LGTSPLOFF+2, fTmp+LGTSPLOFF+3);
- break;
- case SS_JITTER:
- fscanf(inf, "%f %f %f", jitter_light_range[nLights],
- jitter_light_range[nLights] + 1,
- jitter_light_range[nLights] + 2);
- break;
- case SS_END:
- lmdef(DEFLIGHT, nLights+1, 0, fTmp);
- localDone = TRUE;
- break;
- default:
- fprintf(stderr, "Unknown LIGHT keyword: %s\n", cmd);
- break;
- }
- }
- nLights++;
- break;
-
- case SS_END:
- done = TRUE;
- break;
- default:
- fprintf(stderr, "Unknown keyword: %s\n", cmd);
- break;
- }
- }
- }
-
-
- /* Set defaults where unspecified */
-
- if (nObjects <= 0) {
- /* If no objects defined, put three cubes in */
- for (nObjects = 0; nObjects < 3; nObjects++) {
- obj_drawlist[nObjects] = &glo_cube;
- obj_data[nObjects] = GetPolyData(obj_drawlist[nObjects]);
- vmatcopy(IdentMat, obj_rotMatrix[nObjects]);
- obj_litMaterial[nObjects] = -1;
- }
- vset(obj_posn[0], 1.35, -0.78, 0.0);
- vset(fTmp, 20.0, 5.0, 17.0);
- GetRotMatrix(obj_rotMatrix[0], fTmp);
- obj_scale[0] = 1.0;
-
- vset(obj_posn[1], -1.35, -0.78, 0.0);
- vset(fTmp, -5.0, 35.0, -35.0);
- GetRotMatrix(obj_rotMatrix[1], fTmp);
- obj_scale[1] = 1.2;
-
- vset(obj_posn[2], 0.00, 1.56, 0.0);
- vset(fTmp, -19.0, 5.0, 5.0);
- GetRotMatrix(obj_rotMatrix[2], fTmp);
- obj_scale[2] = 1.4;
- }
-
- /* Assign a gray material to any undefined objects */
- lmdef(DEFMATERIAL, iMaterial, 0, FlatGray);
- lmdef(DEFMATERIAL, iMaterial+1, 0, FlatGrayA);
- lmdef(DEFMATERIAL, iMaterial+2, 0, FlatGrayH);
- for (i=0; i<nObjects; i++)
- if (obj_litMaterial[i] < 0) {
- obj_litMaterial[i] = iMaterial;
- obj_shadowMaterial[i] = iMaterial+1;
- obj_highMaterial[i] = iMaterial+2;
- }
-
- /* If no lights defined, put in a red one and a blue one */
- if (nLights <= 0) {
- lmdef(DEFLIGHT, 1, 0, RightRed);
- lmdef(DEFLIGHT, 2, 0, LeftBlue);
- nLights = 2;
- vset(light_posn[0], 100.0, 100.0, 100.0);
- vset(light_posn[1], -100.0, 100.0, 100.0);
- vset(jitter_light_range[0], 10.0, 10.0, 10.0);
- vset(jitter_light_range[1], 5.0, 5.0, 5.0);
- }
-
- /* Define the light model */
- lmdef(DEFLMODEL, 1, 0, theLModel);
- lmbind(LMODEL, 1);
- }
-
-
- int
- FindCommand(char buf[]) {
- int i;
-
- for (i=0; i<NSCENECMDS; i++)
- if (strncmp(buf, SceneCommands[i].name,
- strlen(SceneCommands[i].name)) == 0)
- return SceneCommands[i].index;
- return SS_UNDEFINED;
- }
-
-
- int
- GetRotMatrix(Matrix aMatrix, float r[]) {
- /* Use GL hardware to get composite rotation matrix */
- pushmatrix();
- loadmatrix(IdentMat);
- rot(r[0], 'x');
- rot(r[1], 'y');
- rot(r[2], 'z');
- getmatrix(aMatrix);
- popmatrix();
- }
-
-
- int
- ReadImg(char *filename, long **pbgImage, int *pbgXsize, int *pbgYsize) {
- register IMAGE *image;
- register int x, y, xsize, ysize;
- register int z, zsize;
- short buf[4096];
-
- if ((image=iopen(filename, "r")) == NULL ) {
- fprintf(stderr,"readimg: can't open input file %s\n",filename);
- return FALSE;
- }
- xsize = image->xsize;
- ysize = image->ysize;
- zsize = image->zsize;
- if(zsize<3) {
- fprintf(stderr,"readimg: this is not an RGB image file\n");
- return FALSE;
- }
-
- *pbgImage = (long *) malloc(xsize * ysize * sizeof(long));
- *pbgXsize = xsize; *pbgYsize = ysize;
-
- for(y=0; y<ysize; y++) {
- getrow(image,buf,y,0); /* Red */
- for (x=0; x<xsize; x++) (*pbgImage)[y*xsize + x] = buf[x] | 0xff000000;
- getrow(image,buf,y,1); /* Green */
- for (x=0; x<xsize; x++) (*pbgImage)[y*xsize + x] |= buf[x] << 8;
- getrow(image,buf,y,2); /* Blue */
- for (x=0; x<xsize; x++) (*pbgImage)[y*xsize + x] |= buf[x] << 16;
- }
- return TRUE;
- }
-